/* Copyright 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Rockchip VPU (video processing unit) encoder library module.
 *
 * This library is not thread-safe.
 */

#ifndef LIBVPU_RK_VEPU_INTERFACE_H_
#define LIBVPU_RK_VEPU_INTERFACE_H_

#include <linux/videodev2.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

/* TODO(wuchengli): Remove these after the header is updated. */
#define V4L2_CID_CUSTOM_BASE               (V4L2_CID_USER_BASE | 0x1000)
#define V4L2_CID_PRIVATE_RK3288_HEADER     (V4L2_CID_CUSTOM_BASE)
#define V4L2_CID_PRIVATE_RK3288_REG_PARAMS (V4L2_CID_CUSTOM_BASE + 1)
#define V4L2_CID_PRIVATE_RK3288_HW_PARAMS  (V4L2_CID_CUSTOM_BASE + 2)
#define V4L2_CID_PRIVATE_RK3288_GET_PARAMS (V4L2_CID_CUSTOM_BASE + 3)

/* The maximum number of controls returned by rk_vepu_get_config(). */
#define MAX_NUM_GET_CONFIG_CTRLS 5

struct rk_vepu_init_param {
  uint32_t width; /* video width */
  uint32_t height; /* video height */
  uint32_t input_format; /* V4L2 fourcc pixel format */
  uint32_t output_format; /* V4L2 fourcc pixel format */
};

struct rk_vepu_runtime_param {
  int32_t framerate_numer; /* frame rate */
  int32_t framerate_denom;
  int32_t bitrate; /* bits per second */
  bool keyframe_request; /* have keyframe request */
};

/**
 * Create and initialize an encoder instance with encode parameters.
 *
 * @param param: vpu encoder parameters, see struct rk_vepu_init_param.
 *
 * @return the encoder instance. NULL if failed.
 */
void *rk_vepu_init(struct rk_vepu_init_param *param);

/**
 * Deinitialize and destroy the encoder instance.
 *
 * @param enc: the instance generated by rk_vepu_init. The implementation will
 *     release the memory in enc.
 */
void rk_vepu_deinit(void *enc);

/**
 * Get configuration for driver to configure the hardware.
 *
 * @param enc: the instance generated by rk_vepu_init.
 * @param num_ctrls: pointer to the number of controls.
 * @param ctrls_ids: pointer to a num_ctrls element array of V4L2 control IDs
 *     corresponding to elements in ctrls.
 * @param payloads: pointer to a num_ctrls element array of pointers to control
 *     payloads.
 * @param payload_sizes: pointer to a num_ctrls element array of sizes for each
 *     payload.
 *
 * Get a set of control payloads and IDs from library for the plugin to pass as
 * V4L2 controls to the driver. num_ctrls, ctrl_ids, payloads, and payload_size
 * are output. The library owns the memory. But it can only change or free the
 * memory on next rk_vepu_get_config() call or rk_vepu_deinit().
 *
 * @return -1 failure, 0 success.
 */
int rk_vepu_get_config(void *enc, size_t *num_ctrls, uint32_t **ctrl_ids,
                       void ***payloads, uint32_t **payload_sizes);

/**
 * Update the encoder configuration by previous encoding output.
 *
 * @param enc: the instance generated by rk_vepu_init.
 * @param config: the configuration got from driver by G_EXT_CTRLS. The caller
 *     owns the memory and the encoder library cannot use the buffer after this
 *     function returns.
 * @param config_size: size of the configuration.
 * @param buffer_size: size of the previous encoded buffer.
 *
 * @return -1 failure, 0 success.
 */
int rk_vepu_update_config(void *enc, void *config, uint32_t config_size,
                          uint32_t buffer_size);

/**
 * Update the runtime parameters.
 *
 * @param enc: the instance generated by rk_vepu_init.
 * @param runtime_param: encoder runtime parameters, see struct
 *    rk_vepu_runtime_param. If bitrate or framerate_numer is 0, it will be
 *    ignored by the library. If keyframe_request is false, keyframe_value will
 *    be ignored.
 *
 * @return -1 failure, 0 success.
 */
int rk_vepu_update_parameter(void *enc,
                             struct rk_vepu_runtime_param *runtime_param);

#endif  // LIBVPU_RK_VEPU_INTERFACE_H_

